package org.spring.springboot.config.avoidRepeatable;

import java.lang.reflect.Method;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.spring.springboot.util.ClinetIP;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class AvoidRepeatableCommitAspect {

	@Autowired
	RedisTemplate jsonRedisTemplate;
	
	//配置个切入点
	@Pointcut("@annotation(org.spring.springboot.config.avoidRepeatable.AvoidRepeatableCommit)")
	public void pointcut() {
	}
	
	@Around("pointcut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {

	      HttpServletRequest request  = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
	      //获取请求的ip
	       String ip = ClinetIP.getIpAddress(request);
	      
	     //获取切入点的注解
	      MethodSignature signature = (MethodSignature) point.getSignature();
	      Method method = signature.getMethod();
	      
	      //获取切入点目标类、方法
	      String className = method.getDeclaringClass().getName();
	      String name = method.getName();
	      //类名和方法名作为key
	      String ipKey = String.format("%s#%s",className,name);
	      int hashCode = Math.abs(ipKey.hashCode());
	      String key = String.format("%s_%d",ip,hashCode);
	      //获取方法的注解
	      AvoidRepeatableCommit avoidRepeatableCommit =  method.getAnnotation(AvoidRepeatableCommit.class);
	     long timeout = avoidRepeatableCommit.timeout();
	      if (timeout < 0){
	         //过期时间5分钟
	         timeout = 60*5;
	      }
	      //以ip和类作为Key
	      String value = (String) jsonRedisTemplate.opsForValue().get(key);
	      if (StringUtils.isNotBlank(value)){
	         return "请勿重复提交";
	      }
	      
	      jsonRedisTemplate.opsForValue().set(key, UUID.randomUUID().toString(),timeout,TimeUnit.MILLISECONDS);
	      //执行方法
	      Object object = point.proceed();
	      return object;
	   }
}
